home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1998 October / Macworld (1998-10).dmg / Shareware World / Info / 1984 AOLM Issue 5 / 1984 AOLM Issue 5.rsrc / TEXT_135.txt < prev    next >
Encoding:
Text File  |  1998-07-29  |  14.2 KB  |  379 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15. How To Write An Award‚ÄìWinning Scripts
  16. AppleScript Part 4
  17. By Stephen Harris
  18. Welcome to the fourth part of 1984-Online‚Äôs series on AppleScript, the Mac‚Äôs best kept secret. Each part builds on the last, so if you missed any of the last three then they can be found in Issues 2, 3 and 4 of 1984-Online Magazine at http://www.1984-online.com. There is a glossary (‚ÄúTechno-babble‚Äù) at the end of this article that explains some of the more technical terms used this month.
  19.  
  20. Scripting The Finder
  21. Probably the most useful scriptable application on your Mac, and one that every user with System 7.5 or greater can use is the Finder. The Finder is not only scriptable but recordable, which makes life even easier. We all, at some point in our Mac-using lives, find ourselves performing mundane and repetitive actions which are ideal candidates for automation by AppleScript.
  22.  
  23. You alone know your needs, but I shall try to cover some of the more useful tasks here, with some handy hints thrown in for good measure.
  24.  
  25. Finder Dictionary
  26. Dictionaries list all the AppleScript commands that an application can use, with information on how to use them. The application‚Äôs dictionary is most commonly held in the application itself. Let‚Äôs open the Finder‚Äôs dictionary now.
  27.  
  28. ‚Ä¢    Open the Script Editor
  29. ‚Ä¢    Choose Open Dictionary from the File menu.
  30. ‚Ä¢    Choose ‚ÄòFinder‚Äô in the System Folder, and click Open.
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59. Now you have the Finder‚Äôs dictionary open. On the left hand side of the window you can see all the commands grouped into suites. If you click on the suites or any of the items in the list, the right hand side of the window shows its description.
  60.  
  61. Setup For This Activity
  62. To do this activity, I‚Äôve made the initial data setup easy for you. 
  63.  
  64. ‚Ä¢    Choose New from the File menu in the Script Editor, cut and paste the following script and run it:
  65.  
  66. tell application "Finder"
  67.     activate
  68.     make new folder at desktop with properties {name:"Original Folder"}
  69.     make new folder at desktop with properties {name:"Backup Folder"}
  70.     make new folder at folder "Original Folder" of desktop with properties ¬¨     
  71.         {name:"Important Folder"}
  72. end tell
  73.  
  74. This has created two folders on your desktop, one‚Äôs called ‚ÄúOriginal Folder‚Äù and the other ‚ÄúBackup Folder‚Äù. Inside ‚ÄúOriginal Folder‚Äù is another folder called ‚ÄúImportant Folder‚Äù and we‚Äôre going to copy this from one folder to another. 
  75.  
  76. Clearing Out Rubbish
  77. Example: Let‚Äôs say we‚Äôve recorded the following script to copy the ‚ÄúImportant Folder‚Äù from the ‚ÄúOriginal Folder‚Äù to the ‚ÄúBackup Folder‚Äù:
  78.  
  79. tell application "Finder"
  80.     activate
  81.     select folder "Original Folder"
  82.     open selection
  83.     select folder "Important Folder" of folder "Original Folder"
  84.     copy selection to folder "Backup Folder"
  85.     close container window of folder "Original Folder"
  86. end tell
  87.  
  88. As you can see, the script contains a lot of rubbish about selecting items and opening folders. When the script is run, all this activity not only wastes time, but is very disruptive too. The script can be edited down to this:
  89.  
  90. tell application "Finder"
  91.     activate
  92.     copy folder "Important Folder" of folder ¬¨
  93.         "Original Folder" to folder "Backup Folder"
  94. end tell
  95.  
  96. The script would serve its purpose: to make a copy of the file ‚ÄòCustomers 2‚Äô in a specific folder. 
  97.  
  98. However, the script assumes that the operation is always going to be successful, which it isn‚Äôt. The first time it‚Äôs run a copy will be made, but the second time it will fail. This is because there will already be an item of that name in the folder. So we need to check whether the file is already there, and handle any errors should one of the folders be missing.
  99.  
  100. First let‚Äôs check whether the file is there, by adding these lines after ‚Äòactivate‚Äô:
  101.  
  102. if exists folder "Important Folder" of folder "Backup Folder" then
  103.     delete folder "Important Folder" of folder "Backup Folder"
  104. end if
  105.  
  106. This will check if ‚ÄúImportant Folder‚Äù exists in ‚ÄúBackup Folder‚Äù, and if it does, ‚ÄúImportant Folder‚Äù will be moved into the Wastebasket.
  107.  
  108. Now for our error handling. We looked at the ‚Äòtry‚Äô statement in the last part of this series, now let‚Äôs put it into practice. This goes on the line after ‚Äòend if‚Äô:
  109.  
  110. try
  111.     copy folder "Important Folder" of folder ¬¨
  112.         "Original Folder" to folder "Backup Folder"
  113. on error
  114.     move folder "Important Folder" of trash to folder "Backup Folder"
  115.     display dialog "The folder could not be copied!" buttons¬¨
  116.          "Cancel" default button 1 with icon stop
  117. end try
  118.     display dialog "The folder was copied successfully!" ¬¨
  119.         buttons "OK" default button 1 with icon note
  120.  
  121. Explained:
  122.  
  123. try
  124.     copy folder "Important Folder" of folder ¬¨
  125.             "Original Folder" to folder "Backup Folder"
  126.  
  127. First we try to copy the folder.
  128.  
  129.     on error
  130.         if exists folder "Important Folder" of trash then
  131.             move folder "Important Folder" of trash to folder "Backup Folder"
  132.         end if
  133.  
  134. If the Finder encounters an error, then we first move the folder we put in the trash (if any) back to its original location.
  135.  
  136.         display dialog "The folder could not be copied!" buttons¬¨
  137.              "Cancel" default button 1 with icon stop
  138.  
  139. Then display a dialogue box with a ‚Äòhelpful‚Äô message and a Cancel button. As we‚Äôve discussed previously, a button called ‚ÄòCancel‚Äô will Cancel the script. If you don‚Äôt want the script to cancel when a Cancel button is pressed but spaces on both sides of the word ‚ÄòCancel‚Äô (you need only include one space before the word, but then the text doesn‚Äôt line up correctly on the button -- such fussiness!).
  140.  
  141.     end try
  142.  
  143. End the try control statement.
  144.  
  145.     display dialog "The folder was copied successfully!" ¬¨
  146.         buttons "OK" default button 1 with icon note
  147.  
  148. If the script is still running (i.e. if an error hasn‚Äôt been encountered and the script cancelled by the user clicking ‚ÄòCancel‚Äô), display a dialogue box to say that the folder has been copied successfully. 
  149.  
  150. ‚Ä¢    Run your script and you should see this:
  151.  
  152.  
  153.  
  154.  
  155.  
  156.  
  157.  
  158.  
  159.  
  160.  
  161. You should also test that the script can handle an error. To test this we need to create a ‚Äòproblem‚Äô for the script. 
  162.  
  163. ‚Ä¢    Move the ‚ÄúImportant Folder‚Äù out of the ‚ÄúOriginal Folder‚Äù and onto your desktop.
  164.  
  165. ‚Ä¢    Run the script again. You should see this:
  166.  
  167.  
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176. Also check that the backup of ‚ÄúImportant Folder‚Äù was moved back from the wastebasket into ‚ÄúBackup Folder‚Äù. If so, the script has done its job perfectly.
  177.  
  178. References
  179. The script works well, although it‚Äôs become a little untidy now. If we wanted to change the name of any of the folders, then we‚Äôd have a lot of editing to do. So instead we‚Äôre going to create variables to hold references to the folders we‚Äôve created. By doing that we only need to edit the folder / file name in one place. Add these lines after ‚Äòactivate‚Äô:
  180.  
  181. set ItemName to "Important Folder"
  182. set OriginalFolder to a reference to folder "Original Folder" of desktop
  183. set BackupFolder to a reference to folder "Backup Folder" of desktop
  184. set ItemToBackup to a reference to folder ItemName of OriginalFolder
  185. set BackedUpItem to a reference to folder ItemName of BackupFolder
  186. set TrashedBackedUpItem to a reference to ItemName of trash
  187.  
  188. Setting these variables with ‚Äòa reference to‚Äô tells AppleScript that they are references to objects (in this case folders).
  189.  
  190. ‚Ä¢    So to use these new variables, we need to change the rest of the script to look like this:
  191.  
  192.     if exists BackedUpItem then
  193.         delete BackedUpItem
  194.     end if
  195.     try
  196.         duplicate ItemToBackup to BackupFolder
  197.     on error
  198.         if exists TrashedBackedUpItem then
  199.             move TrashedBackedUpItem to BackupFolder
  200.         end if
  201.         display dialog "The folder could not be copied!" buttons ¬¨
  202.             "Cancel" default button 1 with icon stop
  203.     end try
  204.     display dialog "The folder was copied successfully!" ¬¨
  205.         buttons "OK" default button 1 with icon note
  206. end tell
  207.  
  208. Notice that instead of the line that read ‚Äòcopy folder "Important Folder" of folder "Original Folder" to folder "Backup Folder"‚Äô, has been changed to ‚Äòduplicate ItemToBackup to BackupFolder‚Äô. Normally, ‚Äòduplicate‚Äô and copy would achieve the same thing. The problem is that we‚Äôre now using references to objects, and when I tested the script with ‚Äòcopy‚Äô, for some reason the reference of ‚ÄòItemToBackup‚Äô was copied into the BackupFolder variable, rather than the files being copied in the Finder. Using ‚Äòduplicate‚Äô works around that. It‚Äôs a good job I test these scripts, eh?
  209.  
  210. ‚Ä¢    Run the script again, and it should work no differently to before.
  211.  
  212. Long File Names
  213. You may have noticed that files are referred to in a very long‚Äìwinded (but user‚Äìfriendly) way. A shortcut to typing these names out, should you be writing a script manually, is to use the ‚Äòpaste reference‚Äô feature.
  214.  
  215. If you single-click on an icon in the Finder, and choose Copy from the Edit menu, then a reference to the object will be placed on the clipboard. If you look at the clipboard you will only see the object‚Äôs name. To use the file reference in Script Editor choose Paste Reference from the Edit menu. 
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235. Processing Lots Of Files
  236. As discussed in last month‚Äôs article (AppleScript Part 3), you can use loops to work your way through many items in a list. We won‚Äôt go into detail about those now, but here is an example ‚Äòdroplet‚Äô script (a script that works when you drop items onto it) that calculates the total size of all the items dropped onto it:
  237.  
  238. on open theList
  239.     set totalSize to 0
  240.     tell application "Finder"
  241.         repeat with x in theList
  242.             set totalSize to (totalSize + (size of x))
  243.         end repeat
  244.         display dialog "The total size is: " & (totalSize as string) & " bytes"
  245.     end tell
  246. end open
  247.  
  248. ‚Ä¢    Cut and paste the above lines into a new script.
  249.  
  250. Let‚Äôs work through the script line by line:
  251.  
  252. on open theList
  253. Anything in a script enclosed in ‚Äòon open‚Äô is only run when items are dropped onto a script, and it must be coded for a script to become a ‚Äòdroplet‚Äô. The variable ‚ÄòtheList‚Äô is a list of items (files and folders) dropped onto the script, and will look something like this: {folder "Goodies" of folder "Adobe Photoshop" of startup disk, folder "Plug-ins" of folder "Adobe Photoshop" of startup disk, file "Adobe Photoshop¬Æ 4.0.1" of folder "Adobe Photoshop" of startup disk}.
  254.  
  255. set totalSize to 0
  256. Then we create a new variable called ‚ÄòtotalSize‚Äô and set its contents to 0.
  257.  
  258. tell application "Finder"
  259. Self explanatory?
  260.  
  261. repeat with x in theList
  262. This is the start of our loop. We repeat with a variable called ‚Äòx‚Äô in the list variable cryptically named ‚ÄòtheList‚Äô. This is a special kind of loop for dealing with items in lists, which have been explained in previous parts of this series. The variable ‚Äòx‚Äô will refer to the current item (file or folder, in this case) in theList. All lines of script after this and until ‚Äòend repeat‚Äô will be performed in the loop.
  263.  
  264. set totalSize to (totalSize + (size of x))
  265. Here we set the ‚ÄòtotalSize‚Äô variable to itself plus the size of ‚Äòx‚Äô, the current item in theList.
  266.  
  267. end repeat
  268. That‚Äôs all we need to do for each item in the list, so we end the loop with ‚Äòend repeat‚Äô.
  269.  
  270. display dialog "The total size is: " & (totalSize as string) & " bytes"
  271. Now display a result in a dialog box.
  272.  
  273. end tell
  274. This stops sending instructions to the application specified in the ‚Äòtell‚Äô statement.
  275.  
  276. end open
  277. This completes our ‚Äòon open‚Äô processing.
  278.  
  279. The script isn‚Äôt perfect, yet. It would probably be better if we show the size in kilobytes, provided the size is 1024 or more bytes. 
  280.  
  281. ‚Ä¢    After ‚Äòend repeat‚Äô we can insert these lines:
  282.  
  283. if totalSize is greater than 1023 then -- we're talking KB
  284.     set totalSize to (totalSize / 1024) -- show in KB
  285.     set totalSize to (round totalSize rounding to nearest)
  286.     set sizeUnit to " KB"
  287. else
  288.     set sizeUnit to " bytes"
  289. end if
  290.  
  291. This will check whether ‚ÄòtotalSize‚Äô is greater than 1023 (a kilobyte or more), and if so, it will divide totalSize by 1024, to show the figure in kilobytes, and ‚Äòround‚Äô it to the nearest who number (the round command can be found in the ‚ÄòNumerics‚Äô dictionary in the Scripting Additions folder). Then we create a variable called ‚ÄòsizeUnit‚Äô, set this to ‚Äú KB‚Äù.
  292.  
  293. Otherwise, if totalSize is less than or equal to 1023, we simply set ‚ÄòsizeUnit‚Äô to ‚Äúbytes‚Äù.
  294.  
  295. ‚Ä¢    Change the ‚Äòdisplay dialog‚Äô statement to:
  296.  
  297. display dialog "The total size is: " & (totalSize as string) & sizeUnit ¬¨
  298.     buttons "OK" default button 1 with icon note
  299.  
  300. so that ‚ÄòsizeUnit‚Äô is shown at the end, so KB or bytes will be displayed as appropriate.
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312. Helpful Droplets
  313. The only thing that‚Äôs missing is a message for when the script is double-clicked. Again, this isn‚Äôt mandatory, but is more helpful than the droplet opening and immediately closing when it‚Äôs doubled clicked.
  314.  
  315. ‚Ä¢    Put this code after ‚Äòend open‚Äô:
  316.  
  317. on run
  318.     set myMsg to ¬¨
  319.         "This script calculates the total size of files and folders dropped onto it. " & return & return ¬¨
  320.         & "To use this script, drop some files onto its icon."
  321.     beep
  322.     display dialog myMsg buttons "Quit" default button 1 with icon stop
  323. end run
  324.  
  325. The code is very simple, ‚Äòon run‚Äô -- when the user double-clicks -- create a variable called ‚ÄòmyMsg‚Äô and set its contents to a message informing the user how to use the script, then beep and show the message on the screen.
  326.  
  327. ‚Ä¢    To test this droplet, save your script as an application on the desktop with a suitable name (such as ‚ÄòCalculate Size Of Items‚Äô), and double-click it. You should see your message:
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.  
  339.  
  340.  
  341.  
  342.  
  343.  
  344. This brings us nicely to the end of this part. We‚Äôve written a script to back up a folder from one place to another in which we used ‚Äòreferences‚Äô so that it could be easily customised to use different files and error handling (the ‚Äòtry‚Ķ on error‚Ķ end try‚Äô control statement) to deal with any problems and supply the user with a friendly-ish error message.
  345.  
  346. The second script we worked on was a ‚Äòdroplet‚Äô that can calculate the total size of the items dropped onto it -- information the Finder cannot currently supply. It can work with any number of files because it uses a loop (‚Äòrepeat‚Ķ end repeat‚Äô control statement). It‚Äôs a helpful droplet too. If you double‚Äìclick it, it‚Äôll display a nice message informing you of its purpose and how it should be used.
  347.  
  348. Here‚Äôs a summary of technical terms used this month:
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.  
  369.  
  370.  
  371.  
  372. Until next month enjoy scripting!.
  373. Comments to:
  374. helpdesk@1984-online.com
  375.  
  376.  
  377.  
  378.  
  379.